package stc.skymobi.netty.handler.codec.http.transformer;

import io.netty.handler.codec.http.FullHttpRequest;
import org.apache.commons.beanutils.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import stc.skymobi.util.DynaBeanUtils;
import stc.skymobi.util.MutablePropertyable;
import stc.skymobi.util.Propertyable;
import stc.skymobi.util.Transformer;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;


/**
 * @author hp
 *
 */
public class CopyRequestPropertyTransformer implements HttpRequestTransformer {

    private static final Logger logger = 
    	LoggerFactory.getLogger(CopyRequestPropertyTransformer.class);
    
    private Transformer  impl;
    private String[]                copyedProperties;
    private	String					propertyHttpRequest;
    private	boolean					useLazyBean = true;
    
    public boolean isUseLazyBean() {
		return useLazyBean;
	}

	public void setUseLazyBean(boolean useLazyBean) {
		this.useLazyBean = useLazyBean;
	}

	public String getPropertyHttpRequest() {
		return propertyHttpRequest;
	}

	public void setPropertyHttpRequest(String propertyHttpRequest) {
		this.propertyHttpRequest = propertyHttpRequest;
	}

	/**
     * @param impl the impl to set
     */
    public void setImpl(Transformer impl) {
        this.impl = impl;
    }

    public void setCopyedProperties(List<String> propertyNames) {
        this.copyedProperties = propertyNames.toArray(new String[propertyNames.size()]);
    }
    
	public List<String> getCopyedProperties() {
		return Arrays.asList( copyedProperties );
	}

    @Override
    public Object transform(FullHttpRequest request) {
        Object bean = impl.transform(request);
        if ( null == bean ) {
            return  null;
        }
        
        if ( bean instanceof MutablePropertyable ) {
            
        	stc.skymobi.util.PropertyableUtils.copyProperties( 
        			(Propertyable)request, (MutablePropertyable)bean, copyedProperties);
			((MutablePropertyable)bean).setProperty(propertyHttpRequest, request);
        }
        else {
	        if ( this.useLazyBean ) {
		        bean = DynaBeanUtils.wrapLazyDynaBean(bean);
	        }
	        
	    	try {
				PropertyUtils.setProperty(bean, propertyHttpRequest, request);
				
			} catch (IllegalAccessException e) {
				logger.error("copy property:", e);
			} catch (InvocationTargetException e) {
				logger.error("copy property:", e);
			} catch (NoSuchMethodException e) {
				logger.error("copy property:", e);
			}
			
	        Propertyable propertyable  = (Propertyable)request;
	        if ( null != propertyable ) {
	            for ( String name : copyedProperties ) {
	            	try {
	            		PropertyUtils.setProperty(bean, name, propertyable.getProperty(name) );
		    		} catch (IllegalAccessException e) {
		    			logger.error("copy property:", e);
		    		} catch (InvocationTargetException e) {
		    			logger.error("copy property:", e);
		    		} catch (NoSuchMethodException e) {
		    			logger.error("copy property:", e);
		    		}
	            }
	        }
        }
			
		return	bean;
    }

}
